package gosopt

import (
	"os"

	"gitee.com/haifengat/gosopt/define"
)

type ReqAuthenticateType func(*define.CThostFtdcReqAuthenticateField, int)

// HFTrade 交易接口
type HFTrade struct {
	InvestorID string
	BrokerID   string
	passWord   string

	req int

	ReqConnect      ReqConnectType
	Release         ReleaseAPIType
	ReqUserLogin    ReqUserLoginType
	ReqAuthenticate ReqAuthenticateType // 认证

	onFrontConnected    OnFrontConnectedType
	onFrontDisConnected OnFrontDisConnectedType
	onRspUserLogin      OnRspUserLoginType
}

func (t *HFTrade) Init() {
	// 执行目录下创建 log目录
	_, err := os.Stat("log")
	if err != nil {
		os.Mkdir("log", os.ModePerm)
	}
	t.req = 3
}

func (t *HFTrade) getReqID() int {
	t.req++
	return t.req
}

// ReqLogin 登录
func (t *HFTrade) ReqLogin(investor, pwd, broker, appID, authCode string) {
	t.InvestorID = investor
	t.passWord = pwd
	t.BrokerID = broker
	f := define.CThostFtdcReqAuthenticateField{}
	copy(f.BrokerID[:], broker)
	copy(f.UserID[:], investor)
	copy(f.AppID[:], appID)
	copy(f.AuthCode[:], authCode)
	t.ReqAuthenticate(&f, t.getReqID())
}

// RegOnFrontConnected 注册前置响应
func (t *HFTrade) RegOnFrontConnected(on OnFrontConnectedType) {
	t.onFrontConnected = on
}

// RegOnFrontDisConnected 注册连接响应
func (t *HFTrade) RegOnFrontDisConnected(on OnFrontDisConnectedType) {
	t.onFrontDisConnected = on
}

// RegOnRspUserLogin 注册登录响应
func (t *HFTrade) RegOnRspUserLogin(on OnRspUserLoginType) {
	t.onRspUserLogin = on
}

func (t *HFTrade) RspAuthenticate(info *define.CThostFtdcRspInfoField) {
	if info.ErrorID == 0 {
		f := define.CThostFtdcReqUserLoginField{}
		copy(f.UserID[:], t.InvestorID)
		copy(f.BrokerID[:], t.BrokerID)
		copy(f.Password[:], t.passWord)
		copy(f.UserProductInfo[:], "@HF")
		t.ReqUserLogin(&f)
	} else if t.onRspUserLogin != nil {
		t.onRspUserLogin(&RspUserLoginField{}, &RspInfoField{ErrorID: int(info.ErrorID), ErrorMsg: Bytes2String(info.ErrorMsg[:])})
	}
}

func (t *HFTrade) RspUserLogin(loginField *define.CThostFtdcRspUserLoginField, infoField *define.CThostFtdcRspInfoField) {
	if t.onRspUserLogin == nil {
		return
	}
	t.onRspUserLogin(&RspUserLoginField{
		TradingDay:  string(loginField.TradingDay[:]),
		LoginTime:   string(loginField.LoginTime[:]),
		BrokerID:    string(loginField.BrokerID[:]),
		UserID:      string(loginField.UserID[:]),
		FrontID:     int(loginField.FrontID),
		SessionID:   int(loginField.SessionID),
		MaxOrderRef: string(loginField.MaxOrderRef[:]),
	}, &RspInfoField{
		ErrorID:  int(infoField.ErrorID),
		ErrorMsg: Bytes2String(infoField.ErrorMsg[:]),
	})
}

func (t *HFTrade) FrontConnected() {
	if t.onFrontConnected != nil {
		t.onFrontConnected()
	}
}

func (t *HFTrade) FrontDisConnected(reason int) {
	if t.onFrontDisConnected != nil {
		t.onFrontDisConnected(reason)
	}
}
